package com.dunglv.flashlight;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends Activity implements OnClickListener,
		OnCheckedChangeListener {
	private ToggleButton startBtn;
	private SeekBar seekBar;
	private boolean isFlashOn;
	private boolean hasFlash;
	public Camera camera;
	public FlashThread runnerFlashlight;
	private MediaPlayer mp;
	private TextView textview1;
	private int intensity;

	StrobeRunner strobeRunner;
	Thread bw;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		startBtn = (ToggleButton) findViewById(R.id.start_btn);
		startBtn.setOnCheckedChangeListener(this);
		hasFlash = getApplicationContext().getPackageManager()
				.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

		// Init strobe thread
		// openCamera();
		strobeRunner = StrobeRunner.getInstance();
		strobeRunner.controller = this;

		if (strobeRunner.isRunning) {

		} else {
			try {

				camera = Camera.open();

				if (camera == null) {
					startBtn.setEnabled(false);
					textview1 = (TextView) findViewById(R.id.textview1);
					textview1.setText(R.string.nocamera);
					return;
				}

				camera.release();
			} catch (RuntimeException ex) {
				startBtn.setEnabled(false);
				textview1 = (TextView) findViewById(R.id.textview1);
				textview1.setText(R.string.nocamera);
				Toast.makeText(getApplicationContext(),
						"Error connecting to camera flash.", Toast.LENGTH_LONG)
						.show();
				return;
			}
		}

		seekBar = (SeekBar) findViewById(R.id.SeekBar);
		seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				intensity = progress;
				if (!startBtn.isChecked()) {
					startBtn.setChecked(true);
				} else {
					turnOffFlash();
					bw = new Thread(strobeRunner);
					bw.start();
				}
				if (intensity > 0) {
					strobeRunner.delay = (seekBar.getMax() + 2 - intensity);
				} else {
					strobeRunner.delay = 0;
				}
				Log.e("progress", "" + intensity);
			}
		});

	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		switch (buttonView.getId()) {
		case R.id.start_btn:
			playSound();
			// Perform action on clicks
			if (isChecked) {
				if (intensity == 0) {
					turnOnFlash();
				} else {
					// turnOffFlash();
					bw = new Thread(strobeRunner);
					bw.start();
					// strobeRunner.delay = (seekBar.getMax() + 2 - intensity);
				}
			} else {
				if (strobeRunner.isRunning) {
					strobeRunner.requestStop = true;
				} else {
					turnOffFlash();
				}
			}

			break;
		default:
			break;
		}

	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		android.os.Process.killProcess(android.os.Process.myPid());
	}

	public void openCamera() {
		camera = Camera.open();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {

		default:
			break;
		}

	}

	/**
	 * Enable flashlight
	 */
	public void turnOnFlash() {

		try {
			if (!hasFlash) {
				showDialogExit();
				return;
			}
			camera = Camera.open();
			Parameters p = camera.getParameters();

			List<String> flashModes = p.getSupportedFlashModes();
			for (String flashMode : flashModes) {
				Log.e("--- FLASH --", flashMode);
			}

			// For device support torch
			if (flashModes != null
					&& flashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
				p.setFlashMode(Parameters.FLASH_MODE_TORCH);
				camera.setParameters(p);
				camera.startPreview();
			} else { // For device donot support flash mode torch
				p.setFlashMode(Parameters.FLASH_MODE_ON);
				camera.setParameters(p);
				camera.startPreview();
				camera.autoFocus(new AutoFocusCallback() {
					public void onAutoFocus(boolean success, Camera camera) {
					}
				});
				// Start thread for strobe in sequence
				startThread();
			}

		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(getBaseContext(), "Exception flashLightOn()",
					Toast.LENGTH_SHORT).show();
			try {
				camera.release();
			} catch (Exception ex) {
				Log.e("BSF torch", "Error releasing camera");
			}
		}
	}

	/**
	 * Disable flashligt
	 */
	public void turnOffFlash() {
		try {

			stopThread();
			if (getPackageManager().hasSystemFeature(
					PackageManager.FEATURE_CAMERA_FLASH)) {

				camera.stopPreview();
				camera.setPreviewCallback(null);
				camera.release();
				camera = null;
				Log.e("turn off", "turn off");
			}
		} catch (Exception e) {
			e.printStackTrace();
			// Toast.makeText(getBaseContext(), "Exception flashLightOff",
			// Toast.LENGTH_SHORT).show();
		}
	}

	/*
	 * Playing sound will play button toggle sound on flash on / off
	 */
	private void playSound() {
		if (isFlashOn) {
			mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_off);
		} else {
			mp = MediaPlayer.create(MainActivity.this, R.raw.light_switch_on);
		}
		mp.setOnCompletionListener(new OnCompletionListener() {

			@Override
			public void onCompletion(MediaPlayer mp) {
				// TODO Auto-generated method stub
				mp.release();
			}
		});
		mp.start();
	}

	/**
	 * Start thread
	 */
	public synchronized void startThread() {
		if (runnerFlashlight == null) {
			Log.v("@", "DoScan.startthread");
			runnerFlashlight = new FlashThread(camera);
			runnerFlashlight.start();
		}
	}

	/**
	 * Stop thread
	 */
	public synchronized void stopThread() {
		if (runnerFlashlight != null) {
			Log.v("@", "DoScan.stopthread");
			runnerFlashlight.requestStop();
			runnerFlashlight = null;
		}
	}

	@SuppressWarnings("deprecation")
	public void showDialogExit() {
		// device doesn't support flash
		// Show alert message and close the application
		AlertDialog alert = new AlertDialog.Builder(MainActivity.this).create();
		alert.setTitle("Error");
		alert.setMessage("Sorry, your device doesn't support flash light!");
		alert.setButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				// closing the application
				finish();
			}
		});
		alert.show();
	}

	@Override
	protected void onStop() {
		strobeRunner.requestStop = true;
		startBtn.setChecked(false);
		super.onStop();
	}

}
